package sign

import (
	"gitee.com/micro-plat/sas/sas/modules/auth/conf"
	"gitee.com/micro-plat/sas/sas/modules/const/enum"
	"github.com/micro-plat/lib4go/net"
	"github.com/micro-plat/lib4go/types"
)

//BuildRaw 生成拼接密钥的原串
func BuildRaw(input map[string]interface{}, key, signType string, connect *conf.ConnectConf) string {
	//若排序为static且配置了fields字段，直接进行原串拼接
	if connect.Sort == enum.Static && connect.GetSortFieldsLen() > 0 {
		return spliceKey(staticRaw(input, connect), key, signType, connect)
	}

	values := net.NewValues()
	for k, v := range input {
		//空参数不加入签名
		if types.IsEmpty(v) {
			continue
		}
		values.Set(k, types.GetString(v))
	}

	//排序类型为all且配置了密钥名时，密钥将加入排序
	if connect.Sort == enum.All && connect.Secret.Name != "" {
		values.Set(connect.Secret.Name, key)
	}

	values.Sort()
	//拼接原串及密钥
	raw := values.Join(connect.KV, connect.Chain)
	return spliceKey(raw, key, signType, connect)
}

//spliceKey 拼接key
func spliceKey(raw, key, signType string, connect *conf.ConnectConf) string {
	//若密钥已加入排序，则不再拼接密钥   || rsa签名不能拼接密钥
	if (connect.Sort == enum.All && connect.Secret.Name != "") || signType == enum.RSAStr {
		return raw
	}

	//若配置了密钥名，则将使用相应的连接符进行拼接
	keyStr := key
	if connect.Secret.Name != "" {
		keyStr = connect.Secret.Name + connect.Secret.KV + keyStr
	}

	//按配置的密钥拼接模式进行密钥拼接
	switch connect.Secret.Mode {
	case enum.Head:
		return keyStr + connect.Secret.Chain + raw
	case enum.HeadTail:
		return keyStr + connect.Secret.Chain + raw + connect.Secret.Chain + keyStr
	default:
		return raw + connect.Secret.Chain + keyStr
	}
}

//staticRaw 静态原串拼接
func staticRaw(input map[string]interface{}, connect *conf.ConnectConf) (raw string) {
	//获取配置中的密钥拼接顺序数组
	fields := connect.GetSortFields()

	//按顺序进行原串拼接
	for k, v := range fields {
		value, ok := input[v]
		if !ok || types.IsEmpty(value) {
			continue
		}
		if k == 0 {
			raw = v + connect.KV + types.GetString(value)
		} else {
			raw = raw + connect.Chain + v + connect.KV + types.GetString(value)
		}
	}
	return
}
